﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using blackhouse.WebNemo.Business.Groups;
using System.Globalization;

namespace blackhouse.WebNemo.Web.Controls {
    public class InlineEditRecordValue : EditRecordValue {

        #region Fields

        private TextBox edit;
        private TextBox edit2;
        private EditType editType = EditType.Undefined;
        private bool displayInline = false;
        private RadioButtonList list;

        #endregion

        #region Properties

        private TextBox EditControl {
            get {
                if (this.edit == null) {
                    this.edit = new TextBox();
                    this.Controls.Add(this.edit);
                }
                return edit;
            }
        }

        private TextBox EditControl2 {
            get {
                if (this.edit2 == null) {
                    this.edit2 = new TextBox();
                    this.Controls.Add(this.edit2);
                }
                return edit2;
            }
        }

        public override bool DisplayInline {
            get { return this.displayInline; }
        }

        #endregion

        #region Methods

        public override string AppendToHolderCssClass() {
            return base.AppendToHolderCssClass() + " inline-edit-" + this.editType.ToString().ToLower();
        }

        private void PrePopulate() {
            this.editType = EditType.TextBox;
            if (this.column.DataType == typeof(System.Byte) || this.column.DataType == typeof(Boolean)) {
                this.editType = EditType.YesNo;
                this.displayInline = true;
            }
            if (this.column.DataType == typeof(String))
                this.displayInline = this.column.Length <= 400;

            if (this.column.DataType == typeof(Int16)
                || this.column.DataType == typeof(Int32)
                || this.column.DataType == typeof(Int64)) {
                this.editType = EditType.Int;
                this.displayInline = true;
            }

            if (this.column.DataType == typeof(float)
                || this.column.DataType == typeof(double)
                || this.column.DataType == typeof(decimal)) {
                this.editType = EditType.Numeric;
                this.displayInline = true;
            }

            if (column.ColumnType == FieldType.DateField) {
                this.editType = EditType.Date;
                this.displayInline = true;
            }

            if (column.ColumnType == FieldType.DateTimeField) {
                this.editType = EditType.DateTime;
                this.displayInline = true;
            }

        }

        protected override void PopulateControl() {
            this.PrePopulate();
            this.Controls.Clear();
            switch (this.editType) {
                case EditType.TextBox:
                    this.PopulateTextBox();
                    break;
                case EditType.YesNo:
                    this.PopulateYesNo();
                    break;
                case EditType.Int:
                    this.PopulateInt();
                    break;
                case EditType.Numeric:
                    this.PopulateNumeric();
                    break;
                case EditType.Date:
                    this.PopulateDate();
                    break;
                case EditType.DateTime:
                    this.PopulateDateTime();
                    break;
                default:
                    this.Visible = false;
                    break;
            }
        }

        public override BaseValidator[] GetValidators() {
            List<BaseValidator> validators = new List<BaseValidator>();
            switch (this.editType) {
                case EditType.Date:
                case EditType.DateTime:
                case EditType.Numeric:
                case EditType.Int:
                case EditType.TextBox:
                    this.EditControl.ID = "InlineEditRecordValue";
                    if (!this.column.AllowNull) {
                        RequiredFieldValidator validator = new RequiredFieldValidator();
                        validator.ControlToValidate = this.EditControl.ID;
                        validator.ErrorMessage = "Pole " + column.Name + " nie może być puste!";
                        validator.Text = "Pole  nie może być puste!";
                        validators.Add(validator);
                    }
                    if (!String.IsNullOrEmpty(this.column.RegexValidation)) {
                        RegularExpressionValidator validator2 = new RegularExpressionValidator();
                        validator2.ControlToValidate = this.EditControl.ID;
                        validator2.ErrorMessage = "Pole " + column.Name + " zawiera niepoprawną wartość!";
                        validator2.Text = "Pole zawiera niepoprawną wartość!";
                        validator2.ValidationExpression = this.column.RegexValidation;
                        validators.Add(validator2);
                    }
                    break;
            }
            return validators.ToArray();
        }

        protected void PopulateTextBox() {

            if (this.record.IsNotNull(this.column.ColumnName))
                this.EditControl.Text = this.record.GetString(this.column.ColumnName);
            else {
                if (this.column.DefaultValue != null)
                    this.EditControl.Text = this.column.DefaultValue.ToString();
            }

            this.EditControl.CssClass = "inputtext";
            if (this.column.Length > 400) {
                this.EditControl.TextMode = TextBoxMode.MultiLine;
                this.EditControl.Wrap = true;
                if (this.column.Length == int.MaxValue)
                    this.EditControl.Rows = 10;
                else
                    this.EditControl.Rows = (int)Math.Ceiling(this.column.Length / 200d);

            }
            if (this.column.Length < int.MaxValue && this.column.Length > 0) {
                this.EditControl.MaxLength = this.column.Length;
            }

        }

        protected void PopulateYesNo() {
            this.list = new RadioButtonList();
            this.list.RepeatDirection = RepeatDirection.Horizontal;
            this.list.RepeatLayout = RepeatLayout.Table;
            this.list.CssClass = "record-yesno";
            ListItem liy, lin;

            bool val = this.record.GetBoolean(this.column.ColumnName);

            liy = new ListItem(); liy.Text = "Tak"; liy.Value = "true"; liy.Selected = val;
            lin = new ListItem(); ; lin.Text = "Nie"; lin.Value = "false"; lin.Selected = !val;
            list.Items.AddRange(new ListItem[] { liy, lin });
            this.Controls.Add(list);
        }

        protected void PopulateInt() {
            this.EditControl.CssClass = "inputtext input-number";
            string columnName = this.column.ColumnName;
            if (this.record.IsNotNull(columnName))
                this.EditControl.Text = this.record.GetInt32(columnName).ToString();
            else {
                this.EditControl.Text = "0";
            }
            AddFilter(@"/[\d\-]/");
        }

        protected void PopulateNumeric() {
            string columnName = this.column.ColumnName;
            if (this.record.IsNotNull(columnName))
                this.EditControl.Text = this.record.GetDouble(columnName).ToString();
            else
                this.EditControl.Text = "0";
            this.EditControl.CssClass = "inputtext input-number input-numeric";
            string sep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
            if (sep == ".")
                sep = @"\" + sep;
            AddFilter(@"/[\d" + sep + "]/");
        }

        protected void PopulateDate() {
            string columnName = this.column.ColumnName;
            if (this.record.IsNotNull(columnName)) {
                this.EditControl.Text = this.record.GetDateTime(columnName).ToString("d MMMM, yyyy");
                this.EditControl.Attributes.Add("orgdate", this.record.GetDateTime(columnName).ToString("dd-MM-yyyy"));
            }
            else
                this.EditControl.Text = "Wybierz datę";
            this.EditControl.CssClass = "inputtext inputdate";

        }

        protected void PopulateDateTime() {
            string columnName = this.column.ColumnName;
            if (this.record.IsNotNull(columnName)) {
                DateTime dt = this.record.GetDateTime(columnName);
                this.EditControl.Text = dt.ToString("d MMMM, yyyy");
                this.EditControl.Attributes.Add("orgdate", dt.ToString("dd-MM-yyyy"));
                this.EditControl2.Text = dt.ToString("HH:mm");
            }
            else {
                this.EditControl.Text = "Wybierz datę";
                this.EditControl2.Text = DateTime.MinValue.ToString("HH:mm");
            }
            this.EditControl.CssClass = "inputtext inputdate";
            this.EditControl2.CssClass = "inputtext inputtextsec inputtime";
        }

        protected void AddFilter(string mask) {
            this.EditControl.Attributes.Add("keyfilter", mask);
        }

        public override string GetValue() {
            if (editType == EditType.TextBox)
                return this.Page.Request[this.EditControl.UniqueID];
            else
                return "";
        }

        public override void ReSetValue(object value) {
            if (editType == EditType.TextBox)
                this.EditControl.Text = value.ToString();
        }

        public override void SaveInRecord() {
            switch (this.editType) {
                case EditType.TextBox:
                    this.record.SetValue(this.column.ColumnName, this.Page.Request[this.EditControl.UniqueID]);
                    break;
                case EditType.YesNo:
                    Boolean val = false;
                    if (Boolean.TryParse(Page.Request[this.list.UniqueID], out val)) {
                        this.record.SetValue(this.column.ColumnName, val);
                    }
                    break;
                case EditType.Int:
                    int val2 = 0;
                    if (int.TryParse(Page.Request[this.EditControl.UniqueID], out val2)) {
                        this.record.SetValue(this.column.ColumnName, val2);
                    }
                    break;
                case EditType.Numeric:
                    double val3 = 0;
                    string numVal = Page.Request[this.EditControl.UniqueID];
                    numVal = numVal.ReplaceEx(",", ".");
                    if (double.TryParse(numVal, NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-US"), out val3)) {
                        this.record.SetValue(this.column.ColumnName, val3);
                    }
                    break;
                case EditType.Date:
                    DateTime val4;
                    if (DateTime.TryParseExact(Page.Request[this.EditControl.UniqueID], "d MMMM, yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None, out val4))
                        this.record.SetValue(this.column.ColumnName, val4);
                    break;
                case EditType.DateTime:
                    string sDate = Page.Request[this.EditControl.UniqueID] + " " + Page.Request[this.EditControl2.UniqueID];
                    DateTime dt;
                    if (DateTime.TryParseExact(sDate, "d MMMM, yyyy HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out dt))
                        this.record.SetValue(this.column.ColumnName, dt);
                    break;
            }
        }

        private enum EditType {
            Undefined,
            TextBox,
            YesNo,
            Int,
            Numeric,
            Date,
            DateTime
        }

        #endregion

    }
}